package com.xiaouyudeguang.common.ditable.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xiaouyudeguang.common.ditable.dao.DiTableDao;
import com.xiaouyudeguang.common.ditable.entity.DiTable;
import com.xiaouyudeguang.common.ditable.service.DiTableService;
import com.xiaouyudeguang.common.exception.BusinessException;
import com.xiaouyudeguang.common.utils.JsonObject;
import com.xiaouyudeguang.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.xiaouyudeguang.common.config.MybatisPlusConfig.TABLE_NAME;

@Slf4j
@Service
public class DiTableServiceImpl extends ServiceImpl<DiTableDao, DiTable> implements DiTableService {

    private static final String fragment = "json -> '$.%s'  %s %s";

    private static final String default_columns = "{\"columns\": [{\"key\": \"id\", \"title\": \"id\", \"width\": 100}, {\"key\": \"created\", \"title\": \"创建时间\", \"width\": 100}]}";

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private DiTableService baseService;

    @Override
    public String save(String tenantId, String appId, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        diTable.setId(null);
        diTable.setAppId(appId);
        diTable.setTenantId(tenantId);
        diTable.setIsDefault(false);
        diTable.setTableName(request.get("tableName").asText());
        diTable.setTableComment(request.get("tableComment").asText());
        ArrayNode jsonNode = JsonObject.createArrayNode();
        ArrayNode arrayNode = diTable.getJson().withArray("columns");
        ArrayNode columnsNode = request.get("data").withArray("columns");
        boolean containsKey = false;
        for (JsonNode columnNode : columnsNode) {
            String key = columnNode.path("key").asText();
            if (StringUtils.isNotBlank(key) && !("id".equals(key) || "created".equals(key))) {
                if (!containsKey) {
                    containsKey = "id".equals(columnNode.path("title").asText());
                }
                jsonNode.add(columnNode);
            }
        }
        for (JsonNode columnNode : arrayNode) {
            String key = columnNode.path("key").asText();
            if (!containsKey || (StringUtils.isBlank(key) || !"id".equals(key))) {
                jsonNode.add(columnNode);
            }
        }
        diTable.getJson().setAll((ObjectNode) request.get("data"));
        diTable.getJson().set("columns", JsonObject.sort(jsonNode));
        save(diTable);
        return diTable.getId();
    }

    @Override
    public boolean saveBatch(String tenantId, String appId, List<JsonNode> dataList) throws Exception {
        List<DiTable> insertList = new ArrayList<>();
        dataList.forEach(data -> {
            insertList.add(DiTable.builder().appId(appId).tenantId(tenantId).tableName(data.get("table_name").asText()).json((ObjectNode) data.get("data")).build());
        });
        return saveBatch(insertList);
    }

    @Override
    public boolean delete(String tenantId, String appId, SFunction<DiTable, ?> function, Object value) throws Exception {
        return remove(lambdaWrapper(tenantId, appId).eq(function, value));
    }

    @Override
    public boolean deleteAll(String tenantId, String appId) throws Exception {
        return remove(lambdaWrapper(tenantId, appId));
    }

    @Override
    public boolean deleteById(String tenantId, String appId, String id) throws BusinessException {
        return removeById(id);
    }

    @Override
    public boolean deleteByIds(String tenantId, String appId, Set<String> ids) throws Exception {
        return removeBatchByIds(ids);
    }

    @Override
    public boolean updateById(String tenantId, String appId, JsonNode request) throws Exception {
        DiTable data = getById(request.get("data").get("id").asText());
        if (data == null) {
            throw new BusinessException("数据已不存在");
        }
        if (!appId.equals(tenantId) && !tenantId.equals(data.getTenantId())) {
            throw new BusinessException("没有操作权限");
        }
        DiTable diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        diTable.setId(data.getId());
        diTable.setAppId(appId);
        diTable.setTenantId(tenantId);
        diTable.setIsDefault(false);
        diTable.setTableName(request.get("tableName").asText());
        diTable.setTableComment(request.get("tableComment").asText());
        ArrayNode jsonNode = JsonObject.createArrayNode();
        ArrayNode arrayNode = diTable.getJson().withArray("columns");
        ArrayNode columnsNode = request.get("data").withArray("columns");
        boolean containsKey = false;
        for (JsonNode columnNode : columnsNode) {
            String key = columnNode.path("key").asText();
            if (StringUtils.isNotBlank(key) && !("id".equals(key) || "created".equals(key))) {
                if (!containsKey) {
                    containsKey = "id".equals(columnNode.path("title").asText());
                }
                jsonNode.add(columnNode);
            }
        }
        for (JsonNode columnNode : arrayNode) {
            String key = columnNode.path("key").asText();
            if (!containsKey || (StringUtils.isBlank(key) || !"id".equals(key))) {
                jsonNode.add(columnNode);
            }
        }
        diTable.getJson().setAll((ObjectNode) request.get("data"));
        diTable.getJson().set("columns", JsonObject.sort(jsonNode));
        return updateById(diTable);
    }


    @Override
    public boolean updateBatch(String tenantId, String appId, List<JsonNode> dataList) throws Exception {
        for (JsonNode data : dataList) {
            updateById(tenantId, appId, data);
        }
        return true;
    }

    @Override
    public JsonNode getById(String tenantId, String appId, String id) throws Exception {
        DiTable data = getById(id);
        if (data == null || (!appId.equals(tenantId) && !tenantId.equals(data.getTenantId()))) {
            return null;
        }
        return fillData(tenantId, appId, data);
    }

    @Override
    public DiTable getOne(String tenantId, String appId, SFunction<DiTable, ?> function, Object value) throws Exception {
        return super.getOne(lambdaWrapper(tenantId, appId).eq(function, value));
    }

    @Override
    public List<ObjectNode> getByIds(String tenantId, String appId, Set<String> ids) throws Exception {
        List<DiTable> dataList = listByIds(ids);
        List<ObjectNode> returnList = new ArrayList<>();
        for (DiTable data : dataList) {
            if (appId.equals(tenantId) || tenantId.equals(data.getTenantId())) {
                returnList.add(fillData(tenantId, appId, data));
            }
        }
        return returnList;
    }

    @Override
    public List<ObjectNode> list(String tenantId, String appId, JsonNode request) throws Exception {
        LambdaQueryWrapper<DiTable> lambdaQueryWrapper = lambdaWrapper(appId, appId, request);
        lambdaQueryWrapper.eq(!appId.equals(tenantId), DiTable::getShareable, true);
        List<DiTable> dataList = list(lambdaQueryWrapper);
        if (!appId.equals(tenantId)) {
            List<DiTable> tenantList = list(lambdaWrapper(tenantId, appId, request));
            if (tenantList != null && !tenantList.isEmpty()) {
                Map<String, List<DiTable>> ditableMap = tenantList.stream().collect(Collectors.groupingBy(DiTable::getTableName));
                for (DiTable item : dataList) {
                    if (!ditableMap.containsKey(item.getTableName())) {
                        tenantList.add(item);
                    }
                }
                dataList = tenantList;
            }
        }
        List<ObjectNode> returnList = new ArrayList<>();
        for (DiTable data : dataList) {
            returnList.add(fillData(tenantId, appId, data));
        }
        return returnList;
    }

    @Override
    public List<DiTable> list(String tenantId, String appId, SFunction<DiTable, ?> function, Object value) throws Exception {
        return super.list(lambdaWrapper(tenantId, appId).eq(function, value));
    }

    @Override
    public List<DiTable> list(String tenantId, String appId, SFunction<DiTable, ?> function, Set<?> values) throws Exception {
        return super.list(lambdaWrapper(tenantId, appId).in(function, values).eq(DiTable::getIsDefault, false));
    }

    @Override
    public PageImpl<ObjectNode> page(String tenantId, String appId, JsonNode request) throws Exception {
        int current = request.path("current").asInt(1);
        int size = request.path("size").asInt(10);
        Page<DiTable> page = page(Page.of(current, size), lambdaWrapper(tenantId, appId, request));
        List<DiTable> dataList = page.getRecords();
        if (dataList.isEmpty()) {
            return new PageImpl<>(Collections.emptyList(), Pageable.unpaged(), 0);
        }
        List<ObjectNode> returnList = new ArrayList<>();
        for (DiTable data : dataList) {
            returnList.add(fillData(tenantId, appId, data));
        }
        Pageable pageable = current < 0 ? Pageable.unpaged() : Pageable.ofSize(size);
        return new PageImpl<>(returnList, pageable, page.getTotal());
    }

    private LambdaQueryWrapper<DiTable> lambdaWrapper(String tenantId, String appId) {
        LambdaQueryWrapper<DiTable> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByAsc(DiTable::getIsDefault);
        lambdaQueryWrapper.orderByDesc(DiTable::getCreated);
        if (appId.equals(tenantId)) {
            lambdaQueryWrapper.eq(DiTable::getAppId, appId);
            lambdaQueryWrapper.eq(DiTable::getTenantId, appId);
        } else {
            lambdaQueryWrapper.eq(DiTable::getAppId, appId);
            lambdaQueryWrapper.eq(DiTable::getTenantId, tenantId);
        }
        return lambdaQueryWrapper;
    }

    private LambdaQueryWrapper<DiTable> lambdaWrapper(String tenantId, String appId, JsonNode request) {
        LambdaQueryWrapper<DiTable> lambdaQueryWrapper = lambdaWrapper(tenantId, appId);
        lambdaQueryWrapper.eq(DiTable::getIsDefault, false);
        ObjectNode data = (ObjectNode) request.get("data");
        if (data != null) {
            lambdaQueryWrapper.like(data.has("tableName"), DiTable::getTableName, data.path("tableName").asText());
            lambdaQueryWrapper.like(data.has("tableComment"), DiTable::getTableComment, data.path("tableComment").asText());
        }
        return lambdaQueryWrapper;
    }

    private ObjectNode fillData(String tenantId, String appId, DiTable data) throws Exception {
        return data.getJson().setAll((ObjectNode) objectMapper.valueToTree(data));
    }

    @Override
    public ObjectNode getTable(String tenantId, String appId, String tableName) throws Exception {
        DiTable data = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (data == null && !appId.equals(tenantId)) {
            data = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (data == null) {
            data = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        TABLE_NAME.remove();
        return data.getJson();
    }

    @Override
    public Map<String, String> getFieldMapping(String tenantId, String appId, String tableName) throws Exception {
        Map<String, String> filedMap = new HashMap<>();
        tableName = StringUtils.lowerCamel(tableName);
        ObjectNode diTable = getTable(tenantId, appId, tableName);
        if (diTable != null) {
            Iterator<Map.Entry<String, JsonNode>> fields = diTable.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> entry = fields.next();
                if (entry.getValue() != null && entry.getValue().get("comment") != null) {
                    filedMap.put(entry.getKey(), entry.getValue().get("comment").asText());
                }
            }
        }
        return filedMap;
    }

    @Override
    public Boolean addColumn(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode data = (ObjectNode) request.get("data");
        String key = data.path("key").asText();
        String title = data.path("title").asText();
        String model = data.path("model").asText();
        if (data.path("key") == null || StringUtils.isBlank(key)) {
            key = title;
            data.put("key", key);
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode columnsNode = jsonNode.withArray("columns");
        for (JsonNode column : columnsNode) {
            if (column.path("title").asText().equals(key)) {
                throw new BusinessException("属性已存在");
            }
            if (data.path("model") != null && StringUtils.isNotBlank(model) && column.path("model").asText().equals(model)) {
                throw new BusinessException("业务对象已被属性" + column.path("title").asText() + "关联");
            }
        }
        ArrayNode columns = JsonObject.createArrayNode();
        columns.addAll(columnsNode);
        columns.add(data);
        diTable.getJson().set("columns", JsonObject.sort(columns));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean updateColumn(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode data = (ObjectNode) request.get("data");
        String key = data.path("key").asText();
        String title = data.path("title").asText();
        String model = data.path("model").asText();
        if (data.path("key") == null || StringUtils.isBlank(key)) {
            key = title;
            data.put("key", key);
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode columnsNode = jsonNode.withArray("columns");
        ArrayNode columns = JsonObject.createArrayNode();
        for (JsonNode column : columnsNode) {
            if (!column.path("key").asText().equals(key)) {
                if (column.path("title").asText().equals(title)) {
                    throw new BusinessException("字段名称不允许重复");
                }
                if (data.path("model") != null && StringUtils.isNotBlank(model) && column.path("model").asText().equals(model)) {
                    throw new BusinessException("业务对象已被属性" + column.path("title").asText() + "关联");
                }
                columns.add(column);
            } else {
                columns.add(data);
            }
        }
        diTable.getJson().set("columns", JsonObject.sort(columns));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean deleteColumn(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode columnsNode = jsonNode.withArray("columns");
        ArrayNode columns = JsonObject.createArrayNode();
        String key = request.get("data").path("key").asText();
        for (JsonNode column : columnsNode) {
            if (!column.path("key").asText().equals(key)) {
                columns.add(column);
            }
        }
        jsonNode.set("columns", JsonObject.sort(columns));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean addAction(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode data = (ObjectNode) request.get("data");
        String key = data.path("key").asText();
        String label = data.path("label").asText();
        if (data.path("key") == null || StringUtils.isBlank(key)) {
            key = label;
            data.put("key", key);
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode actionsNode = jsonNode.withArray("actions");
        for (JsonNode action : actionsNode) {
            if (action.path("label").asText().equals(label) || action.path("key").asText().equals(key)) {
                throw new BusinessException("操作已存在");
            }
        }
        ArrayNode actions = JsonObject.createArrayNode();
        actions.addAll(actionsNode);
        actions.add(data);
        diTable.getJson().set("actions", JsonObject.sort(actions));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean updateAction(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode data = (ObjectNode) request.get("data");
        String key = data.path("key").asText();
        String label = data.path("label").asText();
        if (data.path("key") == null || StringUtils.isBlank(key)) {
            key = label;
            data.put("key", key);
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode actionsNode = jsonNode.withArray("actions");
        ArrayNode actions = JsonObject.createArrayNode();
        for (JsonNode action : actionsNode) {
            if (!action.path("key").asText().equals(key)) {
                if (action.path("label").asText().equals(label)) {
                    throw new BusinessException("操作名称不允许重复");
                }
                actions.add(action);
            } else {
                actions.add(data);
            }
        }
        diTable.getJson().set("actions", JsonObject.sort(actions));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean deleteAction(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode actionsNode = jsonNode.withArray("actions");
        ArrayNode actions = JsonObject.createArrayNode();
        String key = request.get("data").path("key").asText();
        for (JsonNode action : actionsNode) {
            if (!action.path("key").asText().equals(key)) {
                actions.add(action);
            }
        }
        jsonNode.set("actions", JsonObject.sort(actions));
        if (diTable.getIsDefault()) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean addTab(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode data = (ObjectNode) request.get("data");
        String key = data.path("key").asText();
        String label = data.path("label").asText();
        if (data.path("key") == null || StringUtils.isBlank(key)) {
            key = label;
            data.put("key", key);
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode tabsNode = jsonNode.withArray("tabs");
        for (JsonNode tab : tabsNode) {
            if (tab.path("label").asText().equals(label) || tab.path("key").asText().equals(key)) {
                throw new BusinessException("标签已存在");
            }
        }
        ArrayNode tabs = JsonObject.createArrayNode();
        tabs.addAll(tabsNode);
        tabs.add(data);
        diTable.getJson().set("tabs", JsonObject.sort(tabs));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean updateTab(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode data = (ObjectNode) request.get("data");
        String key = data.path("key").asText();
        String label = data.path("label").asText();
        if (data.path("key") == null || StringUtils.isBlank(key)) {
            key = label;
            data.put("key", key);
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode tabsNode = jsonNode.withArray("tabs");
        ArrayNode tabs = JsonObject.createArrayNode();
        for (JsonNode tab : tabsNode) {
            if (!tab.path("key").asText().equals(key)) {
                if (tab.path("label").asText().equals(label)) {
                    throw new BusinessException("标签名称不允许重复");
                }
                tabs.add(tab);
            } else {
                tabs.add(data);
            }
        }
        diTable.getJson().set("tabs", JsonObject.sort(tabs));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }

    @Override
    public Boolean deleteTab(String tenantId, String appId, String tableName, JsonNode request) throws Exception {
        DiTable diTable = getOne(lambdaWrapper(tenantId, appId).eq(DiTable::getTableName, tableName));
        if (diTable == null && !appId.equals(tenantId)) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getTableName, tableName).eq(DiTable::getShareable, true));
        }
        if (diTable == null) {
            diTable = getOne(lambdaWrapper(appId, appId).eq(DiTable::getIsDefault, true));
        }
        ObjectNode jsonNode = diTable.getJson();
        ArrayNode tabsNode = jsonNode.withArray("tabs");
        ArrayNode tabs = JsonObject.createArrayNode();
        String key = request.get("data").path("key").asText();
        for (JsonNode tab : tabsNode) {
            if (!tab.path("key").asText().equals(key)) {
                tabs.add(tab);
            }
        }
        jsonNode.set("tabs", JsonObject.sort(tabs));
        if (diTable.getIsDefault() || !tenantId.equals(diTable.getTenantId())) {
            diTable.setId(null);
            diTable.setIsDefault(false);
            diTable.setTenantId(tenantId);
            diTable.setTableName(tableName);
            diTable.setTableComment(request.path("keyword").asText());
        }
        return saveOrUpdate(diTable);
    }
}